#pragma once

#include "blocking_queue.h"
#include "chunk.h"

#include <filesystem>
#include <string>
#include <vector>

/**
 * @brief 外部排序器：负责数据生成、分块流水线与多路归并。
 */
class ExternalSorter {
public:
    /**
     * @brief 排序流程的配置参数。
     */
    struct Config {
        std::string input_file          = "input_numbers.txt";   ///< 原始输入文件名。
        std::filesystem::path temp_dir  = "runs";                ///< 临时 run 目录。
        std::string output_file         = "sorted_output.txt";   ///< 最终输出文件名。
        std::size_t total_numbers       = 200'000;               ///< 输入记录总数。
        std::size_t chunk_size          = 25'000;                ///< 每个 chunk 的记录数。
        std::uint32_t rng_seed          = 123456789;             ///< 随机数种子，便于复现。
    };

    /**
     * @brief 使用指定配置初始化排序器。
     */
    explicit ExternalSorter(Config cfg);

    /**
     * @brief 执行外部排序的完整流程。
     *
     * @note 顺序：清理环境 → 生成输入 → 读/排/写流水线 → 多路归并 → 清理临时数据。
     */
    void run();

private:
    /**
     * @brief 写线程上下文：记录 run 文件路径并提供互斥同步。
     */
    struct WriterContext {
        std::mutex mutex;                  ///< 写线程之间共享的互斥量。
        std::vector<std::string> paths;    ///< 每个 chunk 对应的 run 文件路径。
    };

    void generate_input();   ///< 阶段 0：生成随机输入文件。
    void launch_pipeline();  ///< 阶段 1~3：启动读/排/写流水线线程。
    void merge_runs();       ///< 阶段 4：多路归并所有 run。
    void cleanup();          ///< 阶段 5：清理临时目录等资源。

    // --- 流水线各阶段的静态线程函数 ---
    static void reader_thread(const std::string& input_path,
                              std::size_t chunk_size,
                              BlockingQueue<Chunk>& queue);

    static void sorter_thread(BlockingQueue<Chunk>& in_queue,
                              BlockingQueue<Chunk>& out_queue);

    static void writer_thread(const std::filesystem::path& output_dir,
                              BlockingQueue<Chunk>& queue,
                              WriterContext& ctx);

    static void multiway_merge_runs(const std::vector<std::string>& run_paths,
                                    const std::string& output_path);

    static bool verify_sorted_file(const std::string& path);

private:
    Config cfg_;                            ///< 当前排序配置。
    BlockingQueue<Chunk> read_to_sort_;     ///< 读线程 → 排序线程 的队列。
    BlockingQueue<Chunk> sort_to_write_;    ///< 排序线程 → 写线程 的队列。
    WriterContext writer_ctx_;              ///< run 路径与同步信息。
};